﻿//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#region << 版 本 注 释 >>

/*----------------------------------------------------------------
* 类 名 称 ：StateMachineManager
* 类 描 述 ：
* 作    者 ：henrychang
* 创建时间 ：2019/1/28 9:53:34
*******************************************************************
* Copyright @ henrychang 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using TouchFish.SingletonClass;
using TouchFish.ToolClass;

namespace TouchFish.StateMachine
{
    public sealed class StateMachineManager : Singleton<StateMachineManager>, IStateMachineManager, ISingleton
    {
        private readonly Dictionary<string, StateMachineBase> m_Fsms;
        private readonly List<StateMachineBase> m_TempFsms;

        /// <summary>
        /// 初始化有限状态机管理器的新实例。
        /// </summary>
        public StateMachineManager()
        {
            m_Fsms = new Dictionary<string, StateMachineBase>();
            m_TempFsms = new List<StateMachineBase>();
        }

        /// <summary>
        /// 获取状态机数量。
        /// </summary>
        public int Count
        {
            get
            {
                return m_Fsms.Count;
            }
        }

        public void OnSingletonInit()
        {
        }

        /// <summary>
        /// 创建状态机。
        /// </summary>
        /// <typeparam name="T">状态机持有者类型。</typeparam>
        /// <param name="owner">状态机持有者。</param>
        /// <param name="states">状态机状态集合。</param>
        /// <returns>要创建的有限状态机。</returns>
        public IStateMachine<T> CreateFsm<T>(T owner, params State<T>[] states) where T : class
        {
            return CreateFsm(string.Empty, owner, states);
        }

        /// <summary>
        /// 创建状态机。
        /// </summary>
        /// <typeparam name="T">状态机持有者类型。</typeparam>
        /// <param name="name">状态机名称。</param>
        /// <param name="owner">状态机持有者。</param>
        /// <param name="states">状态机状态集合。</param>
        /// <returns>要创建的状态机。</returns>
        public IStateMachine<T> CreateFsm<T>(string name, T owner, params State<T>[] states) where T : class
        {
            if (HasFsm<T>(name))
            {
                throw new Exception(StringUtil.Format("Already exist FSM '{0}'.", StringUtil.GetFullName<T>(name)));
            }

            StateMachine<T> fsm = new StateMachine<T>(name, owner, states);
            m_Fsms.Add(StringUtil.GetFullName<T>(name), fsm);
            return fsm;
        }

        /// <summary>
        /// 检查是否存在状态机。
        /// </summary>
        /// <typeparam name="T">状态机持有者类型。</typeparam>
        /// <returns>是否存在状态机。</returns>
        public bool HasFsm<T>() where T : class
        {
            return InternalHasFsm(StringUtil.GetFullName<T>(string.Empty));
        }

        /// <summary>
        /// 检查是否存在状态机。
        /// </summary>
        /// <param name="ownerType">状态机持有者类型。</param>
        /// <returns>是否存在有限状态机。</returns>
        public bool HasFsm(Type ownerType)
        {
            if (ownerType == null)
            {
                throw new Exception("Owner type is invalid.");
            }

            return InternalHasFsm(StringUtil.GetFullName(ownerType, string.Empty));
        }

        /// <summary>
        /// 检查是否存在状态机。
        /// </summary>
        /// <typeparam name="T">状态机持有者类型。</typeparam>
        /// <param name="name">状态机名称。</param>
        /// <returns>是否存在有限状态机。</returns>
        public bool HasFsm<T>(string name) where T : class
        {
            return InternalHasFsm(StringUtil.GetFullName<T>(name));
        }

        /// <summary>
        /// 检查是否存在状态机。
        /// </summary>
        /// <param name="ownerType">状态机持有者类型。</param>
        /// <param name="name">状态机名称。</param>
        /// <returns>是否存在状态机。</returns>
        public bool HasFsm(Type ownerType, string name)
        {
            if (ownerType == null)
            {
                throw new Exception("Owner type is invalid.");
            }

            return InternalHasFsm(StringUtil.GetFullName(ownerType, name));
        }

        ///// <summary>
        ///// 有限状态机管理器轮询。
        ///// </summary>
        ///// <param name="elapseSeconds">逻辑流逝时间，以秒为单位。</param>
        ///// <param name="realElapseSeconds">真实流逝时间，以秒为单位。</param>
        //internal void Update()
        //{
        //    m_TempFsms.Clear();
        //    if (m_Fsms.Count <= 0)
        //    {
        //        return;
        //    }

        //    foreach (KeyValuePair<string, StateMachineBase> fsm in m_Fsms)
        //    {
        //        m_TempFsms.Add(fsm.Value);
        //    }

        //    foreach (StateMachineBase fsm in m_TempFsms)
        //    {
        //        if (fsm.IsDestroyed)
        //        {
        //            continue;
        //        }

        //        fsm.Update();
        //    }
        //}

        ///// <summary>
        ///// 关闭并清理有限状态机管理器。
        ///// </summary>
        //internal void Shutdown()
        //{
        //    foreach (KeyValuePair<string, StateMachineBase> fsm in m_Fsms)
        //    {
        //        fsm.Value.Shutdown();
        //    }

        //    m_Fsms.Clear();
        //    m_TempFsms.Clear();
        //}

        ///// <summary>
        ///// 获取有限状态机。
        ///// </summary>
        ///// <typeparam name="T">有限状态机持有者类型。</typeparam>
        ///// <returns>要获取的有限状态机。</returns>
        //public IStateMachine<T> GetFsm<T>() where T : class
        //{
        //    return (IStateMachine<T>)InternalGetFsm(StringUtil.GetFullName<T>(string.Empty));
        //}

        ///// <summary>
        ///// 获取有限状态机。
        ///// </summary>
        ///// <param name="ownerType">有限状态机持有者类型。</param>
        ///// <returns>要获取的有限状态机。</returns>
        //public StateMachineBase GetFsm(Type ownerType)
        //{
        //    if (ownerType == null)
        //    {
        //        throw new Exception("Owner type is invalid.");
        //    }

        //    return InternalGetFsm(StringUtil.GetFullName(ownerType, string.Empty));
        //}

        ///// <summary>
        ///// 获取状态机。
        ///// </summary>
        ///// <typeparam name="T">状态机持有者类型。</typeparam>
        ///// <param name="name">状态机名称。</param>
        ///// <returns>要获取的状态机。</returns>
        //public IStateMachine<T> GetFsm<T>(string name) where T : class
        //{
        //    return (IStateMachine<T>)InternalGetFsm(StringUtil.GetFullName<T>(name));
        //}

        ///// <summary>
        ///// 获取状态机。
        ///// </summary>
        ///// <param name="ownerType">状态机持有者类型。</param>
        ///// <param name="name">状态机名称。</param>
        ///// <returns>要获取的状态机。</returns>
        //public StateMachineBase GetFsm(Type ownerType, string name)
        //{
        //    if (ownerType == null)
        //    {
        //        throw new Exception("Owner type is invalid.");
        //    }

        //    return InternalGetFsm(StringUtil.GetFullName(ownerType, name));
        //}

        ///// <summary>
        ///// 获取所有有限状态机。
        ///// </summary>
        ///// <returns>所有有限状态机。</returns>
        //public StateMachineBase[] GetAllFsms()
        //{
        //    int index = 0;
        //    StateMachineBase[] results = new StateMachineBase[m_Fsms.Count];
        //    foreach (KeyValuePair<string, StateMachineBase> fsm in m_Fsms)
        //    {
        //        results[index++] = fsm.Value;
        //    }

        //    return results;
        //}

        ///// <summary>
        ///// 获取所有状态机。
        ///// </summary>
        ///// <param name="results">所有状态机。</param>
        //public void GetAllFsms(List<StateMachineBase> results)
        //{
        //    if (results == null)
        //    {
        //        throw new Exception("Results is invalid.");
        //    }

        //    results.Clear();
        //    foreach (KeyValuePair<string, StateMachineBase> fsm in m_Fsms)
        //    {
        //        results.Add(fsm.Value);
        //    }
        //}

        ///// <summary>
        ///// 销毁状态机。
        ///// </summary>
        ///// <typeparam name="T">状态机持有者类型。</typeparam>
        ///// <returns>是否销毁有限状态机成功。</returns>
        //public bool DestroyFsm<T>() where T : class
        //{
        //    return InternalDestroyFsm(StringUtil.GetFullName<T>(string.Empty));
        //}

        ///// <summary>
        ///// 销毁状态机。
        ///// </summary>
        ///// <param name="ownerType">状态机持有者类型。</param>
        ///// <returns>是否销毁状态机成功。</returns>
        //public bool DestroyFsm(Type ownerType)
        //{
        //    if (ownerType == null)
        //    {
        //        throw new Exception("Owner type is invalid.");
        //    }

        //    return InternalDestroyFsm(StringUtil.GetFullName(ownerType, string.Empty));
        //}

        ///// <summary>
        ///// 销毁状态机。
        ///// </summary>
        ///// <typeparam name="T">状态机持有者类型。</typeparam>
        ///// <param name="name">要销毁的状态机名称。</param>
        ///// <returns>是否销毁有限状态机成功。</returns>
        //public bool DestroyFsm<T>(string name) where T : class
        //{
        //    return InternalDestroyFsm(StringUtil.GetFullName<T>(name));
        //}

        ///// <summary>
        ///// 销毁状态机。
        ///// </summary>
        ///// <param name="ownerType">状态机持有者类型。</param>
        ///// <param name="name">要销毁的状态机名称。</param>
        ///// <returns>是否销毁状态机成功。</returns>
        //public bool DestroyFsm(Type ownerType, string name)
        //{
        //    if (ownerType == null)
        //    {
        //        throw new Exception("Owner type is invalid.");
        //    }

        //    return InternalDestroyFsm(StringUtil.GetFullName(ownerType, name));
        //}

        ///// <summary>
        ///// 销毁状态机。
        ///// </summary>
        ///// <typeparam name="T">状态机持有者类型。</typeparam>
        ///// <param name="fsm">要销毁的状态机。</param>
        ///// <returns>是否销毁状态机成功。</returns>
        //public bool DestroyFsm<T>(IStateMachine<T> fsm) where T : class
        //{
        //    if (fsm == null)
        //    {
        //        throw new Exception("FSM is invalid.");
        //    }

        //    return InternalDestroyFsm(StringUtil.GetFullName<T>(fsm.Name));
        //}

        ///// <summary>
        ///// 销毁状态机。
        ///// </summary>
        ///// <param name="fsm">要销毁的状态机。</param>
        ///// <returns>是否销毁状态机成功。</returns>
        //public bool DestroyFsm(StateMachineBase fsm)
        //{
        //    if (fsm == null)
        //    {
        //        throw new Exception("FSM is invalid.");
        //    }

        //    return InternalDestroyFsm(StringUtil.GetFullName(fsm.OwnerType, fsm.Name));
        //}

        private bool InternalHasFsm(string fullName)
        {
            return m_Fsms.ContainsKey(fullName);
        }

        //private StateMachineBase InternalGetFsm(string fullName)
        //{
        //    StateMachineBase fsm = null;
        //    if (m_Fsms.TryGetValue(fullName, out fsm))
        //    {
        //        return fsm;
        //    }

        //    return null;
        //}

        //private bool InternalDestroyFsm(string fullName)
        //{
        //    StateMachineBase fsm = null;
        //    if (m_Fsms.TryGetValue(fullName, out fsm))
        //    {
        //        fsm.Shutdown();
        //        return m_Fsms.Remove(fullName);
        //    }

        //    return false;
        //}
    }
}